package com.xbongbong.paas.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.jxc.abstracts.AbstractJxcAddDataService;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormDataEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.pojo.AssociatedBusinessAfterSavePojo;
import com.xbongbong.paas.pojo.dto.FormDataAddDTO;
import com.xbongbong.paas.pojo.dto.SaasFormSaveDTO;
import com.xbongbong.paas.pojo.vo.FormDataAddVO;
import com.xbongbong.paas.service.dynamic.help.DynamicHelp;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.paas.util.FormDataUtil;
import com.xbongbong.pro.domain.entity.ReRollBackEntity;
import com.xbongbong.pro.enums.errorcodes.BuinessDefaultErrorCodeEnum;
import com.xbongbong.pro.formdata.pojo.vo.BeforeSaveVO;
import com.xbongbong.pro.formdata.pojo.vo.SaveVO;
import com.xbongbong.process.operate.ProcessStartHelp;
import com.xbongbong.saas.domain.entity.ReturnedPurchaseSubDataEntity;
import com.xbongbong.saas.domain.entity.ext.ReturnedPurchaseEntityExt;
import com.xbongbong.saas.enums.OperateModuleTypeEnum;
import com.xbongbong.saas.enums.ReturnedPurchaseStatusEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ReturnedPurchaseEnum;
import com.xbongbong.saas.help.SaasSaveHelp;
import com.xbongbong.saas.help.SaasUpdateHelp;
import com.xbongbong.saas.model.ReturnedPurchaseModel;
import com.xbongbong.saas.model.ReturnedPurchaseSubDataModel;
import com.xbongbong.saas.service.ReturnedPurchaseService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

import static com.xbongbong.saas.toolbox.help.FastJsonHelper.getDoubleOrDefaultFromFormData;

/**
 *
 * @author 魏荣杰
 * @date 2021/1/4 15:45
 * @since
 * @version
 */
@Service("returnedPurchaseFormDataServiceImpl")
public class ReturnedPurchaseFormDataServiceImpl extends AbstractJxcAddDataService {
    private static final Logger LOG = LoggerFactory.getLogger(ReturnedPurchaseFormDataServiceImpl.class);

    @Resource
    private SaasSaveHelp saasSaveHelp;
    @Resource
    private SaasUpdateHelp saasUpdateHelp;
    @Resource
    private ProcessStartHelp processStartHelp;
    @Resource
    private ReturnedPurchaseModel returnedPurchaseModel;
    @Resource
    private ReturnedPurchaseService returnedPurchaseService;
    @Resource
    private DynamicHelp dynamicHelp;
    @Resource
    private ReturnedPurchaseSubDataModel returnedPurchaseSubDataModel;

    @Override
    public List<Integer> businessList() {
        return Arrays.asList(XbbRefTypeEnum.RETURNED_PURCHASE.getCode());
    }


    @Override
    public SaveVO save(FormDataAddDTO formDataAddDTO, BeforeSaveVO beforeSaveVO, PaasFormEntityExt paasFormEntity, PaasFormDataEntity paasFormDataEntity) throws XbbException {
        Long dataId = 0L;
        String corpid = formDataAddDTO.getCorpid();
        Integer saasMark = formDataAddDTO.getSaasMark();
        Integer businessType = formDataAddDTO.getBusinessType();
        try {
            AssociatedBusinessAfterSavePojo associatedBusinessAfterSavePojo = null;
            UserVO userVO = getUserName(formDataAddDTO, paasFormDataEntity);
            Integer noApprovalRequired = beforeSaveVO.getNoApprovalRequired();
            if (Objects.equals(1, noApprovalRequired)) {
                JSONObject returnedPurchaseData = (JSONObject) paasFormDataEntity.getData().clone();
                ReturnedPurchaseEntityExt returnedPurchaseEntityExt = new ReturnedPurchaseEntityExt();
                BeanUtil.copyProperties(paasFormDataEntity, returnedPurchaseEntityExt);

                // 关联产品特殊处理
                JSONObject returnedPurchaseDataList = returnedPurchaseEntityExt.getData();
                //关联付款单发票字段处理
                JSONArray purchaseInvoiceArray = returnedPurchaseData.getJSONArray(ReturnedPurchaseEnum.INVOICES.getAttr());
                JSONArray paySheetArray = returnedPurchaseData.getJSONArray(ReturnedPurchaseEnum.PAY_SHEETS.getAttr());
                saasSaveHelp.formatLinkBusiness4SaveBySerialNo(returnedPurchaseDataList, ReturnedPurchaseEnum.INVOICES.getAttr(), ReturnedPurchaseEnum.INVOICES_LINKED_TEXT.getAttr(), ReturnedPurchaseEnum.INVOICES.getFieldType());
                saasSaveHelp.formatLinkBusiness4SaveBySerialNo(returnedPurchaseDataList, ReturnedPurchaseEnum.PAY_SHEETS.getAttr(), ReturnedPurchaseEnum.PAY_SHEETS_LINKED_TEXT.getAttr(), ReturnedPurchaseEnum.PAY_SHEETS.getFieldType());
                //合计退款金额在afterSave中处理，根据回款单是否创建成功来处理
                Double returnedPurchaseAmount = getDoubleOrDefaultFromFormData(returnedPurchaseDataList, ReturnedPurchaseEnum.RETURNED_PURCHASE_AMOUNT.getAttr(), 0D);
//                boolean isPaySheetIsProcess = processStartHelp.processFormJudge(corpid, XbbRefTypeEnum.PAY_SHEET.getCode());
//                boolean isPurchaseInvoiceIsProcess = processStartHelp.processFormJudge(corpid, XbbRefTypeEnum.PURCHASE_INVOICE.getCode());
//                if (isPaySheetIsProcess) {
//                    returnedPurchaseDataList.put(ReturnedPurchaseEnum.RETURNED_PURCHASE_AMOUNT.getAttr(), 0D);
//                }
                JSONArray productArray = saasSaveHelp.formatSelectProduct4Save2(returnedPurchaseDataList, ReturnedPurchaseEnum.PRODUCTS.getAttr());
                // 设置待出库
                returnedPurchaseDataList.put(ReturnedPurchaseEnum.STATUS.getAttr(), ReturnedPurchaseStatusEnum.WAIT_OUTSTOCK.getStatus());
                FormDataUtil.removeSystemData(returnedPurchaseDataList);
                Object richTextData = removeRichText(returnedPurchaseDataList);
                returnedPurchaseEntityExt.setData(returnedPurchaseDataList);
                returnedPurchaseModel.insert(returnedPurchaseEntityExt);
                dataId = returnedPurchaseEntityExt.getId();
                associatedBusinessAfterSavePojo = new AssociatedBusinessAfterSavePojo(purchaseInvoiceArray, paySheetArray, null, returnedPurchaseAmount, new ReRollBackEntity(), null, null);

                returnedPurchaseEntityExt.getData().put(ReturnedPurchaseEnum.PRODUCTS.getAttr(), productArray);

                // 设置属性用于返回
                setPartialAttributes(dataId, returnedPurchaseEntityExt.getSubFormData(), returnedPurchaseEntityExt.getData(), returnedPurchaseEntityExt.getAddTime(),
                        returnedPurchaseEntityExt.getUpdateTime(), paasFormDataEntity, beforeSaveVO);

                //文件柜数据保存
                saveFile(formDataAddDTO, paasFormDataEntity, userVO);
                //富文本数据保存
                saveRichText(formDataAddDTO, paasFormDataEntity, richTextData);
            }
            return new SaveVO(noApprovalRequired, paasFormDataEntity, dataId, userVO, associatedBusinessAfterSavePojo);
        } catch (XbbException e) {
            LOG.warn(BuinessDefaultErrorCodeEnum.API_ERROR_200018.getMsg(),e);
            saveRollBack(dataId, corpid, saasMark, businessType);
            throw e;
        } catch (Exception e) {
            LOG.error(BuinessDefaultErrorCodeEnum.API_ERROR_200018.getMsg(),e);
            saveRollBack(dataId, corpid, saasMark, businessType);
            throw new XbbException(BuinessDefaultErrorCodeEnum.API_ERROR_200018);
        }
    }

    @Override
    public void saveRollBack(Long id, String corpid, Integer saasMark, Integer businessType) throws XbbException {
        if (id == null || id == 0 || corpid == null || saasMark == null) {
            return ;
        }
        IndexTypeEnum indexTypeEnum = getIndexTypeEnum(corpid, saasMark, businessType);
        //删除主表es数据
        physicalDeleteFormData(id, corpid, indexTypeEnum);
        // 子表单的删除
        List<ReturnedPurchaseSubDataEntity> returnedPurchaseSubDataEntities= returnedPurchaseSubDataModel.getByDataId(id, corpid);
        if (CollectionsUtil.isNotEmpty(returnedPurchaseSubDataEntities)) {
            physicalDeleteSubBatch(corpid, returnedPurchaseSubDataEntities, IndexTypeEnum.IDX_SAAS_RETURNED_PURCHASE_SUB);
        }
    }

    @Override
    public FormDataAddVO afterSave(FormDataAddDTO formDataAddDTO, BeforeSaveVO beforeSaveVO, SaveVO saveVO, PaasFormEntityExt paasFormEntity, PaasFormDataEntity paasFormDataEntity) throws XbbException {
        FormDataAddVO formDataAddVO = new FormDataAddVO();
        Long dataId = saveVO.getDataId();
        String corpid = formDataAddDTO.getCorpid();
        Integer saasMark = formDataAddDTO.getSaasMark();
        Integer businessType = formDataAddDTO.getBusinessType();
        try {
            if (Objects.equals(1, saveVO.getNoApprovalRequired())) {
                SaasFormSaveDTO saasFormSaveDTO = new SaasFormSaveDTO();
                BeanUtil.copyProperties(formDataAddDTO, saasFormSaveDTO);
                packageSaasFormInsertSaveDTO(saasFormSaveDTO, paasFormDataEntity);
                ReturnedPurchaseEntityExt returnedPurchaseEntityExt = new ReturnedPurchaseEntityExt();
                returnedPurchaseEntityExt.setId(paasFormDataEntity.getId());
                returnedPurchaseEntityExt.setCorpid(paasFormDataEntity.getCorpid());
                returnedPurchaseEntityExt.setData(paasFormDataEntity.getData());
                returnedPurchaseEntityExt.setSubFormData(paasFormDataEntity.getSubFormData());
                returnedPurchaseEntityExt.setSerialNo(paasFormDataEntity.getSerialNo());
                saasFormSaveDTO.setSaasNeedRedundantAttrPoJo(beforeSaveVO.getSaasNeedRedundantAttrPojo());
                returnedPurchaseService.afterSave(saasFormSaveDTO, returnedPurchaseEntityExt, saveVO.getAssociatedBusinessAfterSavePojo());
                // log
                afterSaveLog(formDataAddDTO, paasFormEntity, paasFormDataEntity, saveVO, beforeSaveVO);
                // 动态处理
                dynamicHelp.addLinkData(saasFormSaveDTO);
                // api
                apiHook(formDataAddDTO, saveVO, beforeSaveVO);
                // 业务规则
                activeRule(formDataAddDTO, beforeSaveVO, paasFormDataEntity, beforeSaveVO.getPaasFormEntityExt());
                formDataAddVO.setMsg(I18nMessageUtil.getMessage(MessageConstant.FORM_ADD_RETURN_MSG));
                formDataAddVO.setCode(PaasConstant.FORM_ADD_RETURN_CODE);
                formDataAddVO.setDataId(saveVO.getDataId());
                formDataAddVO.setFormDataId(saveVO.getDataId());
            } else {
                formDataAddVO.setMsg(I18nMessageUtil.getMessage(MessageConstant.FORM_ADD_PROCESS_RETURN_MSG));
                formDataAddVO.setCode(PaasConstant.FORM_ADD_PROCESS_RETURN_CODE);
            }
            return formDataAddVO;
        }  catch (XbbException e) {
            LOG.warn(BuinessDefaultErrorCodeEnum.API_ERROR_200018.getMsg(),e);
            saveRollBack(dataId, corpid, saasMark, businessType);
            throw e;
        } catch (Exception e) {
            LOG.error(BuinessDefaultErrorCodeEnum.API_ERROR_200018.getMsg(),e);
            saveRollBack(dataId, corpid, saasMark, businessType);
            throw new XbbException(BuinessDefaultErrorCodeEnum.API_ERROR_200018);
        }
    }

    @Override
    public void afterSaveLog(FormDataAddDTO formDataAddDTO, PaasFormEntityExt paasFormEntityExt, PaasFormDataEntity newPaasFormDataEntity, SaveVO saveVO, BeforeSaveVO beforeSaveVO) throws XbbException {
        boolean isImport = Objects.equals(1, formDataAddDTO.getIsImport());
        if (isImport) {
            return;
        }
        String logName = newPaasFormDataEntity.getSerialNo();
        saveLogger(formDataAddDTO, newPaasFormDataEntity, logName, XbbRefTypeEnum.RETURNED_PURCHASE.getName(), OperateModuleTypeEnum.RETURN_PURCHASE, saveVO, beforeSaveVO);
    }

    @Override
    public void apiHook(FormDataAddDTO formDataAddDTO, SaveVO saveVO, BeforeSaveVO beforeSaveVO) throws XbbException {
        lowCodeExecuteService(formDataAddDTO, saveVO, beforeSaveVO);
    }

    @Override
    public SaveVO saveForWorkflow(FormDataAddDTO formDataAddDTO, BeforeSaveVO beforeSaveVO, PaasFormEntityExt paasFormEntity, PaasFormDataEntity paasFormDataEntity) throws XbbException {
        Long dataId = 0L;
        String corpid = formDataAddDTO.getCorpid();
        Integer saasMark = formDataAddDTO.getSaasMark();
        Integer businessType = formDataAddDTO.getBusinessType();
        try {
            AssociatedBusinessAfterSavePojo associatedBusinessAfterSavePojo = null;
            UserVO userVO = getUserName(formDataAddDTO, paasFormDataEntity);
            Integer noApprovalRequired = beforeSaveVO.getNoApprovalRequired();

            JSONObject returnedPurchaseData = (JSONObject) paasFormDataEntity.getData().clone();
            ReturnedPurchaseEntityExt returnedPurchaseEntityExt = new ReturnedPurchaseEntityExt();
            BeanUtil.copyProperties(paasFormDataEntity, returnedPurchaseEntityExt);

            // 关联产品特殊处理
            JSONObject returnedPurchaseDataList = returnedPurchaseEntityExt.getData();
            //关联付款单发票字段处理
            JSONArray purchaseInvoiceArray = returnedPurchaseData.getJSONArray(ReturnedPurchaseEnum.INVOICES.getAttr());
            JSONArray paySheetArray = returnedPurchaseData.getJSONArray(ReturnedPurchaseEnum.PAY_SHEETS.getAttr());
            saasSaveHelp.formatLinkBusiness4SaveBySerialNo(returnedPurchaseDataList, ReturnedPurchaseEnum.INVOICES.getAttr(), ReturnedPurchaseEnum.INVOICES_LINKED_TEXT.getAttr(), ReturnedPurchaseEnum.INVOICES.getFieldType());
            saasSaveHelp.formatLinkBusiness4SaveBySerialNo(returnedPurchaseDataList, ReturnedPurchaseEnum.PAY_SHEETS.getAttr(), ReturnedPurchaseEnum.PAY_SHEETS_LINKED_TEXT.getAttr(), ReturnedPurchaseEnum.PAY_SHEETS.getFieldType());
            //合计退款金额在afterSave中处理，根据回款单是否创建成功来处理
            Double returnedPurchaseAmount = getDoubleOrDefaultFromFormData(returnedPurchaseDataList, ReturnedPurchaseEnum.RETURNED_PURCHASE_AMOUNT.getAttr(), 0D);
//            boolean isPaySheetIsProcess = processStartHelp.processFormJudge(corpid, XbbRefTypeEnum.PAY_SHEET.getCode());
//            boolean isPurchaseInvoiceIsProcess = processStartHelp.processFormJudge(corpid, XbbRefTypeEnum.PURCHASE_INVOICE.getCode());
//            if (isPaySheetIsProcess) {
//                returnedPurchaseDataList.put(ReturnedPurchaseEnum.RETURNED_PURCHASE_AMOUNT.getAttr(), 0D);
//            }
            JSONArray productArray = saasSaveHelp.formatSelectProduct4Save2(returnedPurchaseDataList, ReturnedPurchaseEnum.PRODUCTS.getAttr());
            // 设置待出库
            returnedPurchaseDataList.put(ReturnedPurchaseEnum.STATUS.getAttr(), ReturnedPurchaseStatusEnum.WAIT_OUTSTOCK.getStatus());
            FormDataUtil.removeSystemData(returnedPurchaseDataList);
            Object richTextData = removeRichText(returnedPurchaseDataList);
            returnedPurchaseEntityExt.setData(returnedPurchaseDataList);
            returnedPurchaseModel.insert(returnedPurchaseEntityExt);
            dataId = returnedPurchaseEntityExt.getId();
            associatedBusinessAfterSavePojo = new AssociatedBusinessAfterSavePojo(purchaseInvoiceArray, paySheetArray, null, returnedPurchaseAmount, new ReRollBackEntity(), null, null);

            returnedPurchaseEntityExt.getData().put(ReturnedPurchaseEnum.PRODUCTS.getAttr(), productArray);

            // 设置属性用于返回
            setPartialAttributes(dataId, returnedPurchaseEntityExt.getSubFormData(), returnedPurchaseEntityExt.getData(), returnedPurchaseEntityExt.getAddTime(), returnedPurchaseEntityExt.getUpdateTime(), paasFormDataEntity, beforeSaveVO);

            //文件柜数据保存
//            saveFile(formDataAddDTO, paasFormDataEntity, userVO);
            //富文本数据保存
            saveRichText(formDataAddDTO, paasFormDataEntity, richTextData);

            paasFormDataEntity.getData().put(ReturnedPurchaseEnum.PRODUCTS.getAttr(), productArray);
            paasFormDataEntity.getData().put(ReturnedPurchaseEnum.INVOICES.getAttr(), purchaseInvoiceArray);
            paasFormDataEntity.getData().put(ReturnedPurchaseEnum.PAY_SHEETS.getAttr(), paySheetArray);
            return new SaveVO(noApprovalRequired, paasFormDataEntity, dataId, userVO, associatedBusinessAfterSavePojo);
        } catch (XbbException e) {
            LOG.warn(BuinessDefaultErrorCodeEnum.API_ERROR_200018.getMsg(),e);
            saveRollBack(dataId, corpid, saasMark, businessType);
            throw e;
        } catch (Exception e) {
            LOG.error(BuinessDefaultErrorCodeEnum.API_ERROR_200018.getMsg(),e);
            saveRollBack(dataId, corpid, saasMark, businessType);
            throw new XbbException(BuinessDefaultErrorCodeEnum.API_ERROR_200018);
        }
    }

    @Override
    public FormDataAddVO afterSaveForWorkflow(FormDataAddDTO formDataAddDTO, BeforeSaveVO beforeSaveVO, SaveVO saveVO, PaasFormEntityExt paasFormEntity, PaasFormDataEntity paasFormDataEntity) throws XbbException {
        FormDataAddVO formDataAddVO = new FormDataAddVO();
        Long dataId = saveVO.getDataId();
        String corpid = formDataAddDTO.getCorpid();
        Integer saasMark = formDataAddDTO.getSaasMark();
        Integer businessType = formDataAddDTO.getBusinessType();
        try {
            SaasFormSaveDTO saasFormSaveDTO = new SaasFormSaveDTO();
            BeanUtil.copyProperties(formDataAddDTO, saasFormSaveDTO);
            packageSaasFormInsertSaveDTO(saasFormSaveDTO, paasFormDataEntity);
            ReturnedPurchaseEntityExt returnedPurchaseEntityExt = new ReturnedPurchaseEntityExt();
            returnedPurchaseEntityExt.setId(paasFormDataEntity.getId());
            returnedPurchaseEntityExt.setCorpid(paasFormDataEntity.getCorpid());
            returnedPurchaseEntityExt.setData(paasFormDataEntity.getData());
            returnedPurchaseEntityExt.setSubFormData(paasFormDataEntity.getSubFormData());
            returnedPurchaseEntityExt.setSerialNo(paasFormDataEntity.getSerialNo());
            saasFormSaveDTO.setSaasNeedRedundantAttrPoJo(beforeSaveVO.getSaasNeedRedundantAttrPojo());
            returnedPurchaseService.afterSaveForWorkflow(saasFormSaveDTO, returnedPurchaseEntityExt, saveVO.getAssociatedBusinessAfterSavePojo());
            // log
//            afterSaveLog(formDataAddDTO, paasFormDataEntity, saveVO, beforeSaveVO);
            // api
//            apiHook(formDataAddDTO, saveVO, beforeSaveVO);
            // 业务规则
//            activeRule(formDataAddDTO, beforeSaveVO, paasFormDataEntity, beforeSaveVO.getPaasFormEntityExt());
            formDataAddVO.setDataId(saveVO.getDataId());
            formDataAddVO.setFormDataId(saveVO.getDataId());
            formDataAddVO.setMsg(I18nMessageUtil.getMessage(MessageConstant.FORM_ADD_RETURN_MSG));
            formDataAddVO.setCode(PaasConstant.FORM_ADD_RETURN_CODE);
            return formDataAddVO;
        }  catch (XbbException e) {
            LOG.warn(BuinessDefaultErrorCodeEnum.API_ERROR_200018.getMsg(),e);
            saveRollBack(dataId, corpid, saasMark, businessType);
            throw e;
        } catch (Exception e) {
            LOG.error(BuinessDefaultErrorCodeEnum.API_ERROR_200018.getMsg(),e);
            saveRollBack(dataId, corpid, saasMark, businessType);
            throw new XbbException(BuinessDefaultErrorCodeEnum.API_ERROR_200018);
        }
    }
}
